package cn.lili.modules.order.order.serviceimpl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderFlow;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dos.RefundFlow;
import cn.lili.modules.order.order.entity.dto.OrderFlowQueryDTO;
import cn.lili.modules.order.order.entity.enums.PayStatusEnum;
import cn.lili.modules.order.order.mapper.RefundFlowMapper;
import cn.lili.modules.order.order.service.OrderFlowService;
import cn.lili.modules.order.order.service.RefundFlowService;
import cn.lili.modules.payment.client.PaymentClient;
import cn.lili.modules.payment.entity.dos.CombinePaymentLog;
import cn.lili.modules.payment.entity.dos.RefundLog;
import cn.lili.modules.payment.entity.dto.RefundParam;
import cn.lili.modules.store.entity.vos.StoreFlowRefundDownloadVO;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * 售后流水业务层实现
 *
 * @author Chopper
 * @since 2020/11/17 7:38 下午
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RefundFlowServiceImpl extends ServiceImpl<RefundFlowMapper, RefundFlow> implements RefundFlowService {


    private final PaymentClient paymentClient;

    private final OrderFlowService orderFlowService;

    private final SettingClient settingClient;

    private final GoodsClient goodsClient;



    @Override
    public List<StoreFlowRefundDownloadVO> getStoreFlowRefundDownloadVO(OrderFlowQueryDTO orderFlowQueryDTO) {
        return baseMapper.getStoreFlowRefundDownloadVO(generatorQueryWrapper(orderFlowQueryDTO));
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void generatorRefundFlow(AfterSale afterSale, OrderItem orderItem, Order order) {
        log.info("xq-afterSale" + JSONObject.toJSONString(afterSale));

        Double payPrice = null;
        RefundFlow refundFlow = new RefundFlow(order);
        if(StringUtils.isNotEmpty(order.getOutTradeNo())){
            CombinePaymentLog combinePaymentLog = paymentClient.getCombinePaymentLogByCombineOutTradeNo(order.getOutTradeNo());
            if(combinePaymentLog!=null){
                payPrice = combinePaymentLog.getPrice();
            }
        }
        //将退款金额，设置成申请金额
        refundFlow.setRefundPrice(afterSale.getActualRefundPrice());
        // 针对门票退款金额计算
        log.info("xq-refundFlow" + JSONObject.toJSONString(refundFlow));
        RefundLog refundLog = paymentClient.refund(RefundParam.builder()
                .sn(refundFlow.getAfterSaleNo())
                .refundReason(refundFlow.getRefundReason())
                .orderSn(refundFlow.getOrderSn())
                .price(refundFlow.getRefundPrice())
                .paymentMethod(order.getPaymentMethod())
                .payPrice(payPrice==null?order.getFlowPrice():payPrice)
                .outTradeNo(order.getOutTradeNo())
                .transactionId(order.getTransactionId())
                .userId(order.getBuyerId())
                .build());
        log.info("xq-refundLog" + JSONObject.toJSONString(refundLog));
        refundFlow.setRefunded(refundLog.getIsRefund());

        refundFlow.setErrorMessage(refundLog.getErrorMessage());

        refundFlow.setOutRefundNo(refundLog.getOutRefundNo());
        refundFlow.setRefundTransactionId(refundLog.getRefundTransactionId());

        orderFlowService.refundOrder(refundFlow, afterSale);
        log.info("xq-----------------------");
        refundFlow.setId(null);
        this.save(refundFlow);
    }


    /**
     * 生成店铺退款流水
     *
     * @param order 订单信息
     */
    @Override
    public void generatorRefundFlow(Order order) {
        // 判断订单是否是付款
        if ((!PayStatusEnum.PAID.name().equals((order.getPayStatus())) && !PayStatusEnum.PLATFORM_PAID.name().equals((order.getPayStatus())))  || order.getFlowPrice() <= 0) {
            return;
        }

        Double payPrice = null;
        RefundFlow refundFlow = new RefundFlow(order);
        if(StringUtils.isNotEmpty(order.getOutTradeNo())){
            CombinePaymentLog combinePaymentLog = paymentClient.getCombinePaymentLogByCombineOutTradeNo(order.getOutTradeNo());
            if(combinePaymentLog!=null){
                payPrice = combinePaymentLog.getPrice();
            }
        }

        RefundLog refundLog = paymentClient.refund(RefundParam.builder()
                .sn(refundFlow.getAfterSaleNo())
                .refundReason(refundFlow.getRefundReason())
                .orderSn(refundFlow.getOrderSn())
                .price(refundFlow.getRefundPrice())
                .paymentMethod(order.getPaymentMethod())
                .payPrice(payPrice==null?order.getFlowPrice():payPrice)
                .outTradeNo(order.getOutTradeNo())
                .transactionId(order.getTransactionId())
                .userId(order.getBuyerId())
                .build());

        refundFlow.setRefunded(refundLog.getIsRefund());

        refundFlow.setErrorMessage(refundLog.getErrorMessage());

        refundFlow.setOutRefundNo(refundLog.getOutRefundNo());
        refundFlow.setRefundTransactionId(refundLog.getRefundTransactionId());

        orderFlowService.refundOrder(refundFlow);

        this.save(refundFlow);
    }


    /**
     * 生成查询wrapper
     *
     * @param orderFlowQueryDTO 搜索参数
     * @return 查询wrapper
     */
    private LambdaQueryWrapper<OrderFlow> generatorQueryWrapper(OrderFlowQueryDTO orderFlowQueryDTO) {


        LambdaQueryWrapper<OrderFlow> lambdaQueryWrapper = Wrappers.lambdaQuery();
        //分销订单过滤是否判定
        lambdaQueryWrapper.isNotNull(orderFlowQueryDTO.getJustDistribution() != null && orderFlowQueryDTO.getJustDistribution(),
                OrderFlow::getDistributionSettlementPrice);

        //售后编号判定
        lambdaQueryWrapper.eq(CharSequenceUtil.isNotEmpty(orderFlowQueryDTO.getOrderSn()),
                OrderFlow::getOrderSn, orderFlowQueryDTO.getOrderSn());

        return lambdaQueryWrapper;
    }

}